package com.renke.jutils;

import java.io.File;
import java.io.FileFilter; 
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.JarURLConnection;  
import java.net.URL;  
import java.net.URLDecoder;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;  
import java.security.MessageDigest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Util {
	/**
     * random
     * @return string $hash
   */
	public static String random()
	{
		return random(6, 0);
	}
	
	public static String random(int length)
	{
		return random(length, 0);
	}
	public static String random(int length, int type)
	{
		String[] chararr = new String[]{
				"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz",
				"0123456789",
				"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
		};
		StringBuffer hash = new StringBuffer("");
		if(type < 0)
			type = 0;
		if(type > 2)
			type = 2;
		String chars = chararr[type];
		int max = chars.length() - 1;
		//PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
		Calendar c = Calendar.getInstance();
		long t = c.getTime().getTime();
		Random r = new Random(t);
		for(int i = 0; i < length; i++)
		{
			hash.append(chars.charAt(r.nextInt(max)));
		}
		return hash.toString();
	}
	
	public static int rand(int min, int max)
	{
		Calendar c = Calendar.getInstance();
		long t = c.getTime().getTime();
		Random r = new Random(t);
		int n = max - min;
		r.nextInt(n);
		return n + min;
	}

	public static String getFileExt(String FileName)
	{
		if(FileName == null || FileName.isEmpty())
			return "";
		int i = FileName.lastIndexOf('.');
		if(i < 0)
			return "";
		return FileName.substring(i + 1);
	}
	public static String getFileName(String FileName, boolean includeExt)
	{
		if(FileName == null || FileName.isEmpty())
			return "";
		String s = "/";//File.separator;
		String[] ss = FileName.split("\\" + s);
		if(!includeExt)
		{
			FileName = ss[ss.length - 1];
			ss = FileName.split("\\.");
		}
		return ss[0];
		//i = FileName.lastIndexOf(File.separatorChar);
		//if(i < 0)
		//	return "";
	}
	
	/**
     * getfirstimg
     * @param string $content
     * @return string $tempurl
   */
	static public String getfirstimg(String string)
	{
		Pattern p = Pattern.compile("<img.+?src=[\\\\]?\"(.+?)[\\\\]?\"", Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(string);
		if(m.find())
		{
			return m.group(1);
		}
		else
			return "";
	}
	
	public static int getimagesnum(String string){
		Pattern p = Pattern.compile("<img.+?src=[\\\\]?\"(.+?)[\\\\]?\"", Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(string);
		int c = 0;
		while(m.find())
			c++;
		return c;
	}
	
    /**
     * formatfilesize
     *
     * @return string $_format
     */
	public static String formatfilesize(String filename)
	{
		File f = new File(filename);
		long size = 0;
		if(f.exists())
			size = f.length();//filesize($filename);
		String _format = "";
		NumberFormat format = NumberFormat.getInstance();
		format.setMinimumFractionDigits(2);
		format.setMaximumFractionDigits(2);
		if (size < 1024){
			_format = size + "B";
		}else if (size < 1024 * 1024){
			_format = format.format(size / 1024.0) + "KB";
		}else if (size < 1024*1024*1024){
			_format = format.format(size / (1024.0 * 1024)) + "MB";
		}
		return _format;
	}
 
  
 	/**
	 * 检测给出IP是否为内网Ip
	 * @param <type> $ip
	 * @return <type> 是内网IP 返回TRUE
	 */
	public static boolean is_private_ip(String ip)
	{
		if(ip == null || ip.isEmpty())
			return true;
		
		String [] i = ip.split("\\.");//explode('.', $ip);
		if (i[0].equals("127")) return true;
		if (i[0].equals("10")) return true;
		int d = Integer.parseInt(i[1]);
		if (i[0].equals("172") && d > 15 && d < 32) return true;
		if (i[0].equals("192") && d == 168) return true;
		return false;
	}
	
	public static String md5(long d)
	{
		//得到一个NumberFormat的实例
        NumberFormat nf = NumberFormat.getInstance();
        //设置是否使用分组
        nf.setGroupingUsed(false);
        return md5(nf.format(d));
	}
	public static String md5(String str)
	{
		if(str == null || str.isEmpty())
			return "";
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes("UTF-8")); 
			byte b[] = md.digest();
			char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7',    
		            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

			StringBuilder sb = new StringBuilder(b.length * 2);    
	        for (int i = 0; i < b.length; i++) {    
	            sb.append(hexChar[(b[i] & 0xf0) >>> 4]);    
	            sb.append(hexChar[b[i] & 0x0f]);    
	        }    
	        return sb.toString(); 
		} catch (Exception e) {
			
			//e.printStackTrace();
//			logger .error("", e);
			return "";
		} 
	}

	public static String encryption(String password) {
		return md5(md5(password));
	}
	
	public static void main(String[] args) {
	}
	
	public static Boolean isNullOrEmpty(String s) {
		return s == null || s.length() == 0 ;
	}
	
	public static Boolean integerNullOrZero(Integer s) {
		return s == null || s == 0;
	}
	
	/** 
     * 从包package中获取所有的Class 
     * @param String
     * @return 
     */  
    public static List<Class<?>> getAllClasses(String packageName){  
          
        //第一个class类的集合  
        List<Class<?>> classes = new ArrayList<Class<?>>();  
        //是否循环迭代  
        boolean recursive = true;  
        //获取包的名字 并进行替换  
        String packageDirName = packageName.replace('.', '/');  
        //定义一个枚举的集合 并进行循环来处理这个目录下的things  
        Enumeration<URL> dirs;  
        try {  
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            //循环迭代下去  
            while (dirs.hasMoreElements()){  
                //获取下一个元素  
                URL url = dirs.nextElement(); 
                //得到协议的名称  
                String protocol = url.getProtocol();  
                //如果是以文件的形式保存在服务器上  
                if ("file".equals(protocol)) {  
                    //获取包的物理路径  
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); 
                    System.out.println(filePath);
                    //以文件的方式扫描整个包下的文件 并添加到集合中  
                    findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);  
                } else if ("jar".equals(protocol)){  
                    //如果是jar包文件   
                    //定义一个JarFile  
                    JarFile jar;  
                    try {  
                        //获取jar  
                        jar = ((JarURLConnection) url.openConnection()).getJarFile();  
                        //从此jar包 得到一个枚举类  
                        Enumeration<JarEntry> entries = jar.entries();  
                        //同样的进行循环迭代  
                        while (entries.hasMoreElements()) {  
                            //获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件  
                            JarEntry entry = entries.nextElement();  
                            String name = entry.getName();  
                            //如果是以/开头的  
                            if (name.charAt(0) == '/') {  
                                //获取后面的字符串  
                                name = name.substring(1);  
                            }  
                            //如果前半部分和定义的包名相同  
                            if (name.startsWith(packageDirName)) {  
                                int idx = name.lastIndexOf('/');  
                                //如果以"/"结尾 是一个包  
                                if (idx != -1) {  
                                    //获取包名 把"/"替换成"."  
                                    packageName = name.substring(0, idx).replace('/', '.');  
                                }  
                                //如果可以迭代下去 并且是一个包  
                                if ((idx != -1) || recursive){  
                                    //如果是一个.class文件 而且不是目录  
                                    if (name.endsWith(".class") && !entry.isDirectory()) {  
                                        //去掉后面的".class" 获取真正的类名  
                                        String className = name.substring(packageName.length() + 1, name.length() - 6);  
                                        try {  
                                            //添加到classes  
                                            classes.add(Class.forName(packageName + '.' + className));  
                                        } catch (ClassNotFoundException e) {  
                                            e.printStackTrace();  
                                        }  
                                      }  
                                }  
                            }  
                        }  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }   
                }  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
         
        return classes;  
    } 
    
    public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, List<Class<?>> classes){  
        //获取此包的目录 建立一个File  
        File dir = new File(packagePath);  
        //如果不存在或者 也不是目录就直接返回  
        if (!dir.exists() || !dir.isDirectory()) {  
            return;  
        }  
        //如果存在 就获取包下的所有文件 包括目录  
        File[] dirfiles = dir.listFiles(new FileFilter() {  
        //自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)  
              public boolean accept(File file) {  
                return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));  
              }  
            });  
        //循环所有文件  
        for (File file : dirfiles) {  
            //如果是目录 则继续扫描  
            if (file.isDirectory()) {  
                findAndAddClassesInPackageByFile(packageName + "." + file.getName(),  
                                      file.getAbsolutePath(),  
                                      recursive,  
                                      classes);  
            }  
            else {  
                //如果是java类文件 去掉后面的.class 只留下类名  
                String className = file.getName().substring(0, file.getName().length() - 6);  
                try {  
                    //添加到集合中去  
                    classes.add(Class.forName(packageName + '.' + className));  
                } catch (ClassNotFoundException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    } 
    
    public static List<String> getClasses(String packageName){
    	List<Class<?>> classes = Util.getAllClasses(packageName);
        List<String> names = new ArrayList<String>();
        for(Class<?> c : classes) {
        	System.out.println(c.toString());
        	String name = c.toString().substring(c.toString().lastIndexOf(".")+1);
        	names.add(name);
        }
    	return names;
    }
    
    public static String getPath(String packageName){
    	//获取包的名字 并进行替换  
        String packageDirName = packageName.replace('.', '/');  
        //定义一个枚举的集合 并进行循环来处理这个目录下的things  
        Enumeration<URL> dirs;  
        String filePath = "";
        try {
			dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
	        //循环迭代下去  
	        while (dirs.hasMoreElements()){ 
	        	URL url = dirs.nextElement();  
	        	filePath = URLDecoder.decode(url.getFile(), "UTF-8");  
	        }
		} catch (IOException e) {
			e.printStackTrace();
		}  
        
    	return filePath.substring(1);
    }
    
    public static boolean isNumber(String str){
    	if(str == null || str.trim().length() == 0) {
    		return false;
    	}
    	try{
     	   Double.parseDouble(str.trim());
     	   return true;
     	  }catch(NumberFormatException e){
         	 return false;
     	  }
    }
    
/*    public static String getIpAddress(HttpServletRequest request) {
    	String ip = null;    //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }    //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }    //还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
    }*/
    
    public static String getRange(String down,String up) {
		String s = "";
		if(!Util.isNullOrEmpty(down)) {
			s = down;
		}
		if(!Util.isNullOrEmpty(up)) {
			if(!Util.isNullOrEmpty(s)) {
				s = s + "-" + up;
			} else {
				s = up;
			}
		}
		if(Util.isNullOrEmpty(s.trim())) {
			s = "&nbsp;";
		}
		return s;
	}
    

	public static void swap(Integer a,Integer b) {
		int imp = a.intValue();
		try {
			Field field = Integer.class.getDeclaredField("value");
			field.setAccessible(true);
			field.set(a, b);
			field.set(b, new Integer(imp));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static String null2String(String s) {
		return s == null ? "" : s;

	}

	public static String null2String(Object s) {
		return s == null ? "" : s.toString();

	}

	public static int getIntValue(String v) {
		return getIntValue(v, -1);
	}

	public static int getIntValue(String v, int def) {
		try {
			return Integer.parseInt(v);
		} catch (Exception ex) {
			return def;
		}
	}

	public static Long getLongValue(String v) {
		return getLongValue(v, -1l);
	}

	public static Long getLongValue(String v, Long def) {
		try {
			return Long.parseLong(v);
		} catch (Exception ex) {
			return def;
		}
	}

	public static Float getFloatValue(String v) {
		return getFloatValue(v, 0);
	}

	public static Float getFloatValue(String v, float def) {
		try {
			return Float.parseFloat(v);
		} catch (Exception ex) {
			return def;
		}
	}

	public static Double getDoubleValue(String v) {
		return getDoubleValue(v, 0);
	}

	public static Double getDoubleValue(String v, double def) {
		try {
			return Double.parseDouble(v);
		} catch (Exception ex) {
			return def;
		}
	}

	public static String getFormatDate(Date v) {
		return getFormatDate(v, "");

	}

	public static String getFormatDate(Date v, String format) {
		try {
			//if(v==null) v= new Date();
			if (format == null || format.isEmpty()) format = "yyyy-MM-dd HH:mm:ss";
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
			// simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
			return simpleDateFormat.format(v);
		} catch (Exception ex) {
			return "";
		}
	}

	public static String getFormatDateGMT(Date v, String format) {
		try {
			if (v == null) v = new Date();
			if (format == null || format.isEmpty()) format = "yyyy-MM-dd HH:mm:ss";
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(v);
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
			simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
			return simpleDateFormat.format(calendar.getTime());
		} catch (Exception ex) {
			return "";
		}
	}

	public static String getFormatDate(Date v, int value) {
		try {
			if (v == null) v = new Date();
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(v);
			SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			calendar.add(Calendar.DAY_OF_MONTH, value);
			//进行时间转换
			String date = sim.format(calendar.getTime());
			return sim.format(calendar.getTime());
		} catch (Exception ex) {
			return "";
		}
	}
	public static Date getString2Date(String strDate) {
		return getString2Date(strDate,"yyyy-MM-dd");
	}
	public static Date getString2Date(String strDate, String format) {
		Date date = null;
		try {
			date = new SimpleDateFormat(format).parse(strDate);
		}
		catch(Exception e) {
			date = null;
		}
		return date;
	}
	public static String  getFirstDayOfMonth(){
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, 0);
		c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
		return getFormatDate(c.getTime(),"yyyy-MM-dd");
	}
	//获取当前月第一天：
	public static String getLastDayOfMonth(){
		//获取当前月最后一天
		Calendar ca = Calendar.getInstance();
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
		return getFormatDate(ca.getTime(),"yyyy-MM-dd");
	}
	public static String replaceUTF8Bom(String str) {
		return str.replace("\uFEFF", "");
	}

	
	
}
